﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;

namespace PubSubLite.Configuration
{
    /// <summary>
    /// Configuration of the PubSubLite bus.
    /// </summary>
    public class BusConfiguration : IBusConfiguration
    {
        public BusConfiguration()
        {

        }


        //private static IBusConfiguration _configuration;
        //internal static IBusConfiguration GetConfiguration()
        //{
        //    if (_configuration == null)
        //    {
        //        lock (_syncRoot)
        //        {
        //            _configuration = Default;
        //        }
        //    }
        //    return _configuration;
        //}

        public static IBusConfiguration Default
        {
            get
            {
                return new BusConfiguration
                {
                    _loggers = new List<IBusLogger>(),
                    _rethrowExceptions = true,
                    _logLevel = BusLogLevel.Errors,
                    _threadSetting = ThreadSettings.MessageHandlingInSeparateThreads
                };
            }
        }

        private List<IBusLogger> _loggers = new List<IBusLogger>();
        private bool _rethrowExceptions = true;
        private bool _logDebugInfo = false;
        private ThreadSettings _threadSetting = ThreadSettings.MessageHandlingInSeparateThreads;
        private BusLogLevel _logLevel;
        private static object _syncRoot = new object();

        private void Log(Exception e)
        {
            if (_logLevel >= BusLogLevel.Errors)
            {
                _loggers.ForEach(x => x.LogException(e));
            }
        }

        private void Log(string info)
        {
            if (_logLevel >= BusLogLevel.None)
            {
                _loggers.ForEach(x => x.LogInfo(info));
            }
        }

        private void LogWarning(string warning)
        {
            if (_logLevel >= BusLogLevel.Warnings)
            {
                _loggers.ForEach(x => x.LogWarning(warning));
            }
        }

        private void LogDebugInfo(string info)
        {
            if (_logDebugInfo)
            {
                _loggers.ForEach(x => x.Debug(info));
            }
        }

        IBusConfigurationSetup IBusConfigurationSetup.RegisterLogger(IBusLogger logger)
        {
            _loggers.Add(logger);
           
            return this;
        }

        IBusConfigurationSetup IBusConfigurationSetup.SetLogLevel(BusLogLevel level)
        {
            _logLevel = level;
            return this;
        }

        IBusConfigurationSetup IBusConfigurationSetup.SetRethrowExceptions(bool rethrow)
        {
            _rethrowExceptions = rethrow;
            return this;
        }

        IBusConfigurationSetup IBusConfigurationSetup.SetLogDebugInfo(bool logDebugInfo)
        {
            _logDebugInfo = logDebugInfo;
            return this;
        }

        IBusConfigurationSetup IBusConfigurationSetup.SetThreadSetting(ThreadSettings setting)
        {
            _threadSetting = setting;
            return this;
        }

        void IBusConfiguration.Log(Exception ex)
        {
            Log(ex);
        }

        void IBusConfiguration.Log(string info)
        {
            Log(info);
        }

        void IBusConfiguration.LogWarning(string warning)
        {
            LogWarning(warning);
        }

        void IBusConfiguration.Debug(string info)
        {
            LogDebugInfo(info);
        }

        bool IBusConfiguration.RethrowExceptions
        {
            get { return _rethrowExceptions; }
        }

        ThreadSettings IBusConfiguration.ThreadSetting
        {
            get { return _threadSetting; }
        }

        PubSubLiteConfigurationSection IBusConfiguration.ConfigSection
        {
            get
            {
                var section = ConfigurationManager.GetSection("PubSubLite");
                if (section != null)
                {
                    return (PubSubLiteConfigurationSection)section;
                }
                return null;
            }
        }

    }
}
